iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
自我挑戰組

ABAP 基礎30天學習筆記系列 第 20

Day20_用ABAP SQL存資料進structure & JOIN使用

  • 分享至 

  • xImage
  •  

原文連結:Working with Structured Data Objects

structure與ABAP SQL

由於內容較多,今天再介紹一天structure,主要會說明structure與SQL的聯合運作,以及join的使用。

只有在 structure 欄位的數量和型別與 FIELDS 中指定的欄位相對應時,SELECT 語句的 INTO 才能正常運作。可以分成以下三種方式撈取資料至structure:

1. 撈特定欄位存入structure

如下,假設structure中只包含三個欄位()的值,FIELDS 中也須按照順序指定相應欄位。如果有欄位對不上將產生error。

DATA connection TYPE st_connection."connection包含了airport_from_id, airport_to_id, carrier_name三個值對應的欄位"

SELECT SINGLE
    FROM /DMO/I_Connection
    FIELDS DepartureAirport, DestinationAirport, \_Airline-Name
    WHERE ...
    INTO @connection.

2. 直接讀整張表的欄位

另外,也可直接將structure型別設為所搜尋的原始資料表,FIELDS 則可直接提取該表所有欄位。

DATA connection TYPE /DMO/I_Connection."直接把原始資料表作為connection的型別"

SELECT SINGLE
    FROM /DMO/I_Connection
    FIELDS *  "選取所有欄位
    WHERE ...
    INTO @connection.

第二個做法的好處是當原始表格或CDS view欄位變動,不須額外改寫structure,但缺點為會額外撈取到前述三個欄位外的多餘資料。

註:資料庫表格在ABAP中亦可直接作為gobal structure型別來建立structure。

註二:效能上會建議僅在欄位少或確實需要大部分欄位時,採用第二種方法。

3. 自動對應欄位

使用 INTO CORRESPONDING FIELDS來達到欄位自動對應,並且可僅截取所需欄位,但structure欄位名稱需要與原始資料表的一致。與稍早提及的CORRESPONDING #( )效果相同。

DATA connection TYPE st_connection.
"connection包含了DepartureAirport, DestinationAirport, \_Airline-Name三個欄位(名稱與原始表格一致)"

SELECT SINGLE
    FROM /DMO/I_Connection
    FIELDS * "選取所有欄位
    WHERE ...
    INTO CORRESPONDING FIELDS OF @connection. "自動對應欄位

4. 自動對應欄位,並為撈取的資料建立別名

由於使用INTO CORRESPONDING FIELDS需要有一致的命名,當structure與撈取欄位命名不一致,可以為撈取欄位加上別名,系統將會透過別名與structure作對應。

DATA connection TYPE st_connection_short.
"connection包含了airport_from_id, airport_to_id, carrier_name三個欄位"

SELECT SINGLE
    FROM /DMO/I_Connection
    FIELDS  DepartureAirport AS  airport_from_id,   "建立別名"
            \_Airline-Name   AS  carrier_name       "建立別名"
    WHERE ...
    INTO CORRESPONDING FIELDS OF @connection."存入撈取的兩個欄位

5. 行內宣告structure

如果要避免欄位對應產生error,也能用一個簡單的方式:當FIELD撈完資料再用INTO自動生成對應structure,無須擔心欄位不一致的問題。

SELECT SINGLE
    FROM /DMO/I_Connection
    FIELDS  DepartureAirport,
            DestinationAirport AS ArrivalAirport,   "建立別名(可選)"
            \_Airline-Name   AS AirlineName       "建立別名(強制)"
    WHERE ...
    INTO @DATA(connection_inline). "行內宣告structure,欄位依序為DepartureAirport,ArrivalAirport,AirlineName

如果有為撈取的資料建立別名,structure生成時也會以別名為主。如果是一般欄位,別名是可選的,如DestinationAirport;但如果欄位為表達式,則必需添加別名,如\_Airline-Name

使用joins抓取來自多個表格的資料

當要從關聯是資料表抓資料時,難免會有跨表格的操作,先前有提及使用CDS View來執行這類任務,但如果沒有可代表目標關聯的CDS View,可以使用SQL joins抓取多個具關連的資料表。

https://ithelp.ithome.com.tw/upload/images/20240916/201138021TX51HooKH.png

以上圖的航班表格為例,airport_from_id欄位存放了機場的三碼代號,欲在同一個SELECT指令中從另一張AIRPORT表格撈出相對應的機場詳細名稱,這時可以使用join同時撈取/DMO/CONNECTION ,/DMO/AIRPORT兩張表。

一個join中包含了以下三部分:

  1. 資料來源:
    指要拿來聯接的資料表或視圖,一個join將連結左側與右側的資料來源。例如程式碼中會分別位於左右側的/DMO/CONNECTION/DMO/AIRPORT資料表。

  2. join條件:
    join會將位於右側的對應資料值,附屬在左側的對應資料之下,舉例而言,上圖左表的CLIENT 結合AIRPORT_ID欄位後可在右表中被對應識別至特定列,其join條件寫法如下:

/DMO/CONNECTION~CLIENT = /DMO/AIRPORT~CLIENT
AND
/DMO/CONNECTION~AIRPORT_FROM_ID = /DMO/AIRPORT~AIRPORT_ID
  1. join類型:
    join的類型會在資料來源未包含吻合的資料筆時產生影響,目前ABAP SQL支援INNER JOIN, LEFT OUTER JOIN 以及 RIGHT OUTER JOIN. 目前最常見的join類型是LEFT OUTER JOIN

join範例1:撈取出發機場

SELECT SINGLE
    "join類型與join條件"
    FROM /dmo/connection AS c
    LEFT OUTER JOIN /dmo/airport AS f 
    ON c~airport_from_id = f~airport_id
    
    FIELDS c~carrier_id, c~connection_id,
   c~airport_from_id,c~airport_to_id,
    f~name AS airport_from_name "從右側的資料來源讀取機場名稱"
    
  WHERE c~carrid      = 'LH'
    AND c~connection  ='0400'
    
    INTO @DATA(connection_join). 

上例中,join類型為關鍵字LEFT OUTER JOINLEFT OUTER JOIN左側資料來源為/dmo/connection ,右側則是/dmo/airport,並分別以別名cf代稱。

除非資料來源在join中出現多次,否則資料來源的別名是可選的。

join條件前置關鍵字為ON,並用~符號連結別名與指定欄位。

join範例2:撈取出發/抵達機場

SELECT SINGLE
    "第一個join類型與join條件"
    FROM ( /dmo/connection AS c
    LEFT OUTER JOIN /dmo/airport AS f 
    ON c~airport_from_id = f~airport_id )
    LEFT OUTER JOIN /dmo/airport AS t 
    ON c~airport_from_id = t~airport_id
    
    FIELDS c~carrier_id, c~connection_id,
   c~airport_from_id,c~airport_to_id,
    f~name AS airport_from_name, "讀取出發機場名稱"
    t~name AS airport_to_name "讀取抵達機場名稱"
    
  WHERE c~carrid      = 'LH'
    AND c~connection  ='0400'
    
    INTO @DATA(connection_join). 

在範例二不只撈取出發機場,還要撈抵達機場,因此在join上需要使用巢狀寫法,在FROM後緊接()先連結第一張表,使用ft分別作為出發機場與抵達機場的別名以區分(即使撈的來源是同一張表/dmo/airport)。

FIELD中分別用別名airport_from_name and airport_to_name來作為出發/抵達機場的欄位名稱。

介紹完structure與SQL結合運用的方式後,明天緊接著來介紹Complex Internal Tables!


上一篇
Day19_structure賦值
下一篇
Day21_複雜Internal Table
系列文
ABAP 基礎30天學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言